#include <vector>

template<typename T>
class ring {
public:
	ring(int size):v(size+1),size(size+1) {

	};
	ring(const ring& r) = delete;
	ring& operator = (const ring& r) = delete;
	ring& operator = (ring&& r) = delete;
	ring(ring&& r) = delete;
	int ring_size() const{
		return size-1;
	}
	int ring_used() const{
		return (tail - head + size) % size;
	}
	int ring_free() const{
		return size - 1 - ring_used();
	}
	bool ring_empty() const {
		return ring_used() == 0;
	}
	bool ring_full() const {
		return ring_free() == 0;
	}
	bool ring_enqueue(typename T data) {
		if (ring_full()) {
			return false;
		}
		v[tail] = data;
#ifdef __GNUC__
		__sync_synchronize();
#endif
		tail = (tail + 1) % size;
		return true;
	}
	bool ring_dequeue(typename T & data) {
		if (ring_empty()) {
			return false;
		}
		data = v[head];
#ifdef __GNUC__
		__sync_synchronize();
#endif
		head = (head + 1) % size;
		return true;
	}
private:
	int head{ 0 };
	int tail{ 0 };
	std::vector<T> v;
	int size;
};
